package com.rivues.util.tools;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.csvreader.CsvWriter;
import com.rivues.core.RivuDataContext;
import com.rivues.module.platform.web.model.AnalyzerReport;
import com.rivues.module.platform.web.model.AnalyzerReportModel;
import com.rivues.module.platform.web.model.JobDetail;
import com.rivues.util.RivuTools;
import com.rivues.util.data.FirstTitle;
import com.rivues.util.data.Level;
import com.rivues.util.data.ReportData;
import com.rivues.util.data.ValueData;
import com.rivues.util.service.cache.CacheHelper;

public class RivuCSVUtil implements ExportFile {
	private static final Logger log = Logger.getLogger(RivuExcelUtil.class);

	private ReportData reportData;
	private AnalyzerReportModel model;
	private AnalyzerReport report;
	private JobDetail job;

	private int page = 1;

	private String headTitle = "报表";

	private String startTime = "";

	private String endTime = "";
	
	private Object cachesize = null;
	
	@Override
	public ReportData getReportData() {
		return reportData;
	}

	private OutputStream out ;
	
	private String[] header =  null ;
	
	private CsvWriter wr = null ;

	public RivuCSVUtil(AnalyzerReportModel model, AnalyzerReport report , OutputStream out) {
		this.model = model;
		reportData = model.getReportData();
		this.report = report;
		this.out = out ;
		wr = new CsvWriter(out, ',', Charset.forName("GBK"));
		if(reportData!=null){
			header = new String[reportData.getCol().getChilderen().size() + (reportData.getRow()!=null && reportData.getRow().getFirstTitle()!=null ? reportData.getRow().getFirstTitle().size(): 0) ];
		}
		
	}
	
	@Override
	public void writeHead(ReportData reportData) throws IOException{
		String[] headers = new String[reportData.getCol().getTitle().get(0).size()] ;
		for (Level colName : reportData.getCol().getTitle().get(0)) {
			headers[reportData.getCol().getTitle().get(0).indexOf(colName)] = colName.getName();
		}
		wr.writeRecord(headers);
	}
	
	@Override
	public synchronized void writeRow(ReportData reportData) throws IOException{
		for(List<ValueData> values : reportData.getData()){
			String[] coantents = new String[values.size()] ;
			for(ValueData valueData : values) {
				if(valueData!=null && values!=null){
					coantents[values.indexOf(valueData)] = String.valueOf(valueData) ;
				}
			}
			wr.writeRecord(coantents);
		}
	}
	
	

	@Override
	public void createFile(boolean limit) throws Exception {
		if(page==1){
			int index = 0;
			if(reportData!=null){
				header = new String[reportData.getData().get(0).size() + (reportData.getRow()!=null && reportData.getRow().getFirstTitle()!=null ? reportData.getRow().getFirstTitle().size(): 0) ];
			}
			if(reportData.getRow()!=null && reportData.getRow().getFirstTitle()!=null){
				for(FirstTitle title : reportData.getRow().getFirstTitle()){
					header[index++] = title.getName() ;
				}
			}
			for (Level colName : reportData.getCol().getTitle().get(0)) {
				header[index] = colName.getName();
				index++;
			}
			wr.writeRecord(header);
		}
		
		
		while (reportData.getData().size()>0) {
			if(limit){
				if(cachesize==null){
					cachesize = CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("system.config.report.ExcelExportPagesize."+model.getReportid(), model.getOrgi());
					if(cachesize==null){
						cachesize = RivuTools.getDicExportCacheSize(model.getReportid(), "system.config.report.ExcelExportPagesize.", model.getOrgi());
					}
					if(cachesize==null){
						cachesize = CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("system.config.report.ExcelExportPagesize", model.getOrgi());
					}
				}
				reportData = RivuTools.getReportData(report , null, model,page++, (cachesize!=null&&cachesize.toString().matches("[\\d]{1,}")) ?Integer.parseInt(cachesize.toString()) : RivuDataContext.EXPORT_PAGE_SIZE);
			}
			for (List<ValueData> valueList : reportData.getData()) {
				String[] contents = new String[reportData.getData().get(0).size() + (reportData.getRow()!=null && reportData.getRow().getFirstTitle()!=null ? reportData.getRow().getFirstTitle().size(): 0)  ];
				int valuesort = 0 ;
				if(reportData.getRow()!=null && reportData.getRow().getFirstTitle()!=null && reportData.getRow().getFirstTitle().size()>0 && valueList.size()>0){
					ValueData valueData = valueList.get(0) ;
					if(valueData.getRow()!=null){
						
						Level level = valueData.getRow() ;
						
						if(level.getColspan()<1){
							level = level.getParent() ;
						}
						int inx = reportData.getRow().getFirstTitle().size()-1 ;
						while(level!=null && inx>=0){
							contents[inx--] = level.getName() ;
							level = level.getParent() ;
						}
						valuesort = reportData.getRow().getFirstTitle().size();
						
					}else{
						continue;
					}
					
					
				}
				for (ValueData data : valueList) {
					contents[valuesort] = String.valueOf(data);
					valuesort++;
				}
				wr.writeRecord(contents);
				Map<String, Object> jobDetailMap = RivuDataContext.getClusterInstance().get(RivuDataContext.DistributeEventEnum.RUNNINGJOB.toString());
				if(model.getExport().getJobDetail()!=null&&jobDetailMap.get(model.getExport().getJobDetail().getId())!=null){
					if(!((JobDetail)(jobDetailMap.get(model.getExport().getJobDetail().getId()))).isFetcher()){
						break ;
					}
				}
				
			}
			if(limit){
				if(reportData.getData().size() < reportData.getPageSize()){
					break ;
				}
			}else{
				break;
			}
			
		}
	}

	@Override
	public void setStartTime(String startTime) {
		this.startTime = startTime;
	}

	@Override
	public void setEndTime(String endTime) {
		this.endTime = endTime;
	}

	@Override
	public String getHeadTitle() {
		return this.headTitle;
	}

	@Override
	public String getStartTime() {
		return this.startTime;
	}

	@Override
	public String getEndTime() {
		return this.startTime;
	}

	@Override
	public void setHeadTitle(String title) {
		this.headTitle = title;
	}

	@Override
	public void createFile(String filename) throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void createSheet(String sheetName) throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setReportData(ReportData reportData) throws Exception {
		// TODO Auto-generated method stub
		this.reportData = reportData;
	}

	@Override
	public void setModel(AnalyzerReportModel model) throws Exception {
		// TODO Auto-generated method stub
		this.model = model;
	}

	@Override
	public void setReport(AnalyzerReport report) throws Exception {
		// TODO Auto-generated method stub
		this.report = report;
	}

	@Override
	public void setRowNum(int rowNum) throws Exception {
		// TODO Auto-generated method stub
	}

	@Override
	public int getRowNum() throws Exception {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void close() {
		wr.close();
	}

	@Override
	public void setPage(int page) throws Exception {
		// TODO Auto-generated method stub
		this.page = page;
	}

	@Override
	public void setOut(OutputStream out) throws Exception {
		// TODO Auto-generated method stub
		this.out = out;
	}

	@Override
	public int getPage() throws Exception {
		// TODO Auto-generated method stub
		return this.page;
	}

	@Override
	public void setJobDetail(JobDetail job) {
		// TODO Auto-generated method stub
		this.job = job;
	}

	@Override
	public JobDetail getJobDetail() {
		// TODO Auto-generated method stub
		return job;
	}
	
}
